/*
Hermes Core: General Purpose Mobile Agent Platform
Copyright (C) 2006 UNICAM - Università degli Studi di Camerino

Group leaders: Flavio Corradini and Emanuela Merelli

Developers: Ezio Bartocci, Diego Bonura, Rosario Culmone,
Davide Lorenzoli, Leonardo Mariani, Francesca Piersigilli, 
Lorenzo Scortichini, Leonardo Vito.

GNU Lesser Public License

This library is free software; you can redistribute it 
and/or modify it under the terms of the GNU Lesser General 
Public License as published by the Free Software Foundation, 
version 2.1 of the License.

This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public 
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

Emanuela Merelli
Dipartimento di Matematica ed Informatica
Università di Camerino
via Madonna delle Carceri, 62032 Camerino, Italy
E.Mail: emanuela.merelli@unicam.it
*/
package hermesV2.basicServices.communication;

import hermesV2.Envelope;
import hermesV2.Message;

import hermesV2.agent.Identificator;

import hermesV2.util.HermesLogger;
import hermesV2.util.VectorQueue;

import java.io.IOException;

import java.util.Hashtable;

/**
 * This is the thread that handles the input of a new message from the core
 * layer. When a new messages is sent to an agent this thread checks if the
 * agent is registered and after it puts the message in the right queue.
 * 
 * @author Diego Bonura
 */
public class InputMessageRequest extends Thread{
    /** The envelope receiver from the core layer. */
    private Envelope<?> envelope;

    /**
     * The hashtable that contains every message queue of every agents
     * registered.
     */
    private Hashtable<String, VectorQueue<Message<?>>> receptionHashtable;


    /**
     * Comment for <code>lazyMessageRequestId</code>
     */
    private Identificator lazyMessageRequestId;
    /**
     * Creates a new InputMessageRequest object.
     * 
     * @param env
     *            The envelope received from the core layer.
     * @param receptionHashtable
     *            The hashtable that contains the message queues.
     */
    public InputMessageRequest(Envelope<?> env, Hashtable<String,  VectorQueue<Message<?>>>  receptionHashtable) {
        this.envelope = env;
        this.receptionHashtable = receptionHashtable;
    }
    /**
     * Creates a new InputMessageRequest object.
     * 
     * @param env
     *            The envelope received from the core layer.
     * @param receptionHashtable
     *            The hashtable that contains the message queues.
     * @param lazyMessageHandleId The identificator of the Lazy message handle instance
     *      */
    public InputMessageRequest(Envelope<?> env, Hashtable<String, VectorQueue<Message<?>>>  receptionHashtable,
            Identificator lazyMessageHandleId) {
        this.envelope = env;
        this.receptionHashtable = receptionHashtable;
        this.lazyMessageRequestId = lazyMessageHandleId;
    }

    /**
     * The run method of the thread checks is the agent is registered and then
     * put the new message into the right queue.
     */
    public void run() {
        try {
            Message<?> message = ((Message<?>) envelope.getObject());
            Identificator agentId = message.getReceiverAgentId();
            if (receptionHashtable.containsKey(agentId.toString())) {
            	VectorQueue<Message<?>> vq = receptionHashtable.get(agentId
                        .toString());
                vq.append(message);

            } else {
                if (lazyMessageRequestId != null) {
                    if (receptionHashtable.containsKey(lazyMessageRequestId
                            .toString())) {
                    	VectorQueue<Message<?>>  vq = receptionHashtable
                                .get(lazyMessageRequestId.toString());
                        vq.append(message);
                        HermesLogger.log(HermesLogger.DEBUG,
                        "Lazy message received");
                    } else {
                        HermesLogger.log(HermesLogger.WARNING,
                                "Something wrog with the lazy message handle");
                    }
                } else {
                    HermesLogger
                            .log(
                                    HermesLogger.DEBUG,
                                    "The Agent "
                                            + agentId
                                            + " is not registered in the Communication Manager and no lazy message handle; the message will be ignored!");
                }

            }
        } catch (ClassNotFoundException cnfe) {
            HermesLogger.log(HermesLogger.WARNING, "ClassNotFoundException",
                    cnfe);
        } catch (IOException ioe) {
            HermesLogger.log(HermesLogger.WARNING, "IOException", ioe);
        }
    }
}